package com.frank.redis.spring;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.CollectionUtils;

import com.frank.redis.JedisPoolFactory;

/**
 * 解析配置文件，初始化bean
 *
 * @author liushaomingdev@163.com
 */
public class JedisBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	private static Logger LOG = LoggerFactory.getLogger(JedisBeanFactoryPostProcessor.class);

	static final String CONF_PRIFIX = "redis.conf.";
	static final String CATEGORY_PRIFIX = "redis.category.";
	static final String ZOOKEEPER_PRIFIX = "redis.zookeeper.";
	static final String ZOOKEEPER = "redis.zookeeper";

	@Override
	public void postProcessBeanFactory(
			ConfigurableListableBeanFactory beanFactory) throws BeansException {
		FACTORY = beanFactory;
		Properties properties = new Properties();
		try {
			properties = PropertiesLoaderUtils.loadAllProperties("redis.properties");
			Properties settings = beanFactory.getBean("settings", Properties.class) ;
			CollectionUtils.mergePropertiesIntoMap(settings, properties);
		} catch (Exception e) {
			LOG.warn("load redis properties", e.getMessage());
		}

		Properties conf = new Properties();
		Map<String, String> zkConf = new HashMap<String, String>();

		for (Object str : properties.keySet()) {
			String key = (String) str;
			String value = properties.getProperty(key);
			if (key.startsWith(ZOOKEEPER_PRIFIX)) {
				key = key.substring(ZOOKEEPER_PRIFIX.length());
				if (value != null && value.length() > 0)
					zkConf.put(key, value);
			}
			else if (key.startsWith(CATEGORY_PRIFIX)) {
				key = "redis-" + key.substring(CATEGORY_PRIFIX.length());
				if (! beanFactory.containsSingleton(key))
					beanFactory.registerSingleton(key, new JedisPoolBean(value));
			}
			else if (key.startsWith(CONF_PRIFIX)) {
				key = key.substring(CONF_PRIFIX.length());
				conf.put(key, value);
			}
		}

		if ("off".equalsIgnoreCase(properties.getProperty(ZOOKEEPER)))
			zkConf.clear();

		beanFactory.registerSingleton("redis_zkConf", zkConf);
		beanFactory.registerSingleton("redis_conf", conf);
		LOG.debug("redis settings: {}", conf);
	}

	private static ConfigurableListableBeanFactory FACTORY;

	/**
	 * 兼容旧版static初始化方式
	 */
	public static JedisPoolFactory getJedisPoolFactory() {
		if (FACTORY == null)
			throw new RuntimeException("init spring before getJedisPool");
		return FACTORY.getBean(JedisPoolFactory.class);
	}
}
